home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / share / gtk-2.0 / demo / stock_browser.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-25  |  15.3 KB  |  547 lines

  1. /* Stock Item and Icon Browser
  2.  *
  3.  * This source code for this demo doesn't demonstrate anything
  4.  * particularly useful in applications. The purpose of the "demo" is
  5.  * just to provide a handy place to browse the available stock icons
  6.  * and stock items.
  7.  */
  8.  
  9. #include <string.h>
  10.  
  11. #include <gtk/gtk.h>
  12.  
  13. static GtkWidget *window = NULL;
  14.  
  15. typedef struct _StockItemInfo StockItemInfo;
  16. struct _StockItemInfo
  17. {
  18.   gchar *id;
  19.   GtkStockItem item;
  20.   GdkPixbuf *small_icon;
  21.   gchar *macro;
  22.   gchar *accel_str;
  23. };
  24.  
  25. /* Make StockItemInfo a boxed type so we can automatically
  26.  * manage memory
  27.  */
  28. #define STOCK_ITEM_INFO_TYPE stock_item_info_get_type ()
  29.  
  30. static void
  31. stock_item_info_free (StockItemInfo *info)
  32. {
  33.   g_free (info->id);
  34.   g_free (info->macro);
  35.   g_free (info->accel_str);
  36.   if (info->small_icon)
  37.     g_object_unref (info->small_icon);
  38.   
  39.   g_free (info);
  40. }
  41.  
  42. static StockItemInfo*
  43. stock_item_info_copy (StockItemInfo *src)
  44. {
  45.   StockItemInfo *info;
  46.  
  47.   info = g_new (StockItemInfo, 1);
  48.   info->id = g_strdup (src->id);
  49.   info->macro = g_strdup (src->macro);
  50.   info->accel_str = g_strdup (src->accel_str);
  51.   
  52.   info->item = src->item;
  53.  
  54.   info->small_icon = src->small_icon;
  55.   if (info->small_icon)
  56.     g_object_ref (info->small_icon);
  57.  
  58.   return info;
  59. }
  60.  
  61. static GType
  62. stock_item_info_get_type (void)
  63. {
  64.   static GType our_type = 0;
  65.   
  66.   if (our_type == 0)
  67.     our_type = g_boxed_type_register_static ("StockItemInfo",
  68.                                              (GBoxedCopyFunc) stock_item_info_copy,
  69.                                              (GBoxedFreeFunc) stock_item_info_free);
  70.  
  71.   return our_type;
  72. }
  73.  
  74. typedef struct _StockItemDisplay StockItemDisplay;
  75. struct _StockItemDisplay
  76. {
  77.   GtkWidget *type_label;
  78.   GtkWidget *macro_label;
  79.   GtkWidget *id_label;
  80.   GtkWidget *label_accel_label;
  81.   GtkWidget *icon_image;
  82. };
  83.  
  84. static gchar*
  85. id_to_macro (const gchar *id)
  86. {
  87.   GString *macro = NULL;
  88.   const gchar *cp;
  89.  
  90.   /* gtk-foo-bar -> GTK_STOCK_FOO_BAR */
  91.  
  92.   macro = g_string_new (NULL);
  93.   
  94.   cp = id;
  95.   
  96.   if (strncmp (cp, "gtk-", 4) == 0)
  97.     {
  98.       g_string_append (macro, "GTK_STOCK_");
  99.       cp += 4;
  100.     }
  101.  
  102.   while (*cp)
  103.     {
  104.       if (*cp == '-')
  105.     g_string_append_c (macro, '_');
  106.       else if (g_ascii_islower (*cp))
  107.     g_string_append_c (macro, g_ascii_toupper (*cp));
  108.       else
  109.     g_string_append_c (macro, *cp);
  110.  
  111.       cp++;
  112.     }
  113.  
  114.   return g_string_free (macro, FALSE);
  115. }
  116.  
  117. static GtkTreeModel*
  118. create_model (void)
  119. {
  120.   GtkListStore *store;
  121.   GSList *ids;
  122.   GSList *tmp_list;
  123.   
  124.   store = gtk_list_store_new (2, STOCK_ITEM_INFO_TYPE, G_TYPE_STRING);
  125.  
  126.   ids = gtk_stock_list_ids ();
  127.   ids = g_slist_sort (ids, (GCompareFunc) strcmp);
  128.   tmp_list = ids;
  129.   while (tmp_list != NULL)
  130.     {
  131.       StockItemInfo info;
  132.       GtkStockItem item;
  133.       GtkTreeIter iter;
  134.       GtkIconSet *icon_set;
  135.       
  136.       info.id = tmp_list->data;
  137.       
  138.       if (gtk_stock_lookup (info.id, &item))
  139.         {
  140.           info.item = item;
  141.         }
  142.       else
  143.         {
  144.           info.item.label = NULL;
  145.           info.item.stock_id = NULL;
  146.           info.item.modifier = 0;
  147.           info.item.keyval = 0;
  148.           info.item.translation_domain = NULL;
  149.         }
  150.  
  151.       /* only show icons for stock IDs that have default icons */
  152.       icon_set = gtk_icon_factory_lookup_default (info.id);
  153.       if (icon_set)
  154.         {
  155.           GtkIconSize *sizes = NULL;
  156.           gint n_sizes = 0;
  157.           gint i;
  158.           GtkIconSize size;
  159.  
  160.           /* See what sizes this stock icon really exists at */
  161.           gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes);
  162.  
  163.           /* Use menu size if it exists, otherwise first size found */
  164.           size = sizes[0];
  165.           i = 0;
  166.           while (i < n_sizes)
  167.             {
  168.               if (sizes[i] == GTK_ICON_SIZE_MENU)
  169.                 {
  170.                   size = GTK_ICON_SIZE_MENU;
  171.                   break;
  172.                 }
  173.               ++i;
  174.             }
  175.           g_free (sizes);
  176.           
  177.           info.small_icon = gtk_widget_render_icon (window, info.id,
  178.                                                     size,
  179.                                                     NULL);
  180.           
  181.           if (size != GTK_ICON_SIZE_MENU)
  182.             {
  183.               /* Make the result the proper size for our thumbnail */
  184.               gint w, h;
  185.               GdkPixbuf *scaled;
  186.               
  187.               gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
  188.               
  189.               scaled = gdk_pixbuf_scale_simple (info.small_icon,
  190.                                                 w, h,
  191.                                                 GDK_INTERP_BILINEAR);
  192.  
  193.               g_object_unref (info.small_icon);
  194.               info.small_icon = scaled;
  195.             }
  196.         }
  197.       else
  198.         info.small_icon = NULL;
  199.  
  200.       if (info.item.keyval != 0)
  201.         {
  202.           info.accel_str = gtk_accelerator_name (info.item.keyval,
  203.                                                  info.item.modifier);
  204.         }
  205.       else
  206.         {
  207.           info.accel_str = g_strdup ("");
  208.         }
  209.  
  210.       info.macro = id_to_macro (info.id);
  211.       
  212.       gtk_list_store_append (store, &iter);
  213.       gtk_list_store_set (store, &iter, 0, &info, 1, info.id, -1);
  214.  
  215.       g_free (info.macro);
  216.       g_free (info.accel_str);
  217.       if (info.small_icon)
  218.         g_object_unref (info.small_icon);
  219.       
  220.       tmp_list = g_slist_next (tmp_list);
  221.     }
  222.   
  223.   g_slist_foreach (ids, (GFunc)g_free, NULL);
  224.   g_slist_free (ids);
  225.  
  226.   return GTK_TREE_MODEL (store);
  227. }
  228.  
  229. /* Finds the largest size at which the given image stock id is
  230.  * available. This would not be useful for a normal application
  231.  */
  232. static GtkIconSize
  233. get_largest_size (const char *id)
  234. {
  235.   GtkIconSet *set = gtk_icon_factory_lookup_default (id);
  236.   GtkIconSize *sizes;
  237.   gint n_sizes, i;
  238.   GtkIconSize best_size = GTK_ICON_SIZE_INVALID;
  239.   gint best_pixels = 0;
  240.  
  241.   gtk_icon_set_get_sizes (set, &sizes, &n_sizes);
  242.  
  243.   for (i = 0; i < n_sizes; i++)
  244.     {
  245.       gint width, height;
  246.       
  247.       gtk_icon_size_lookup (sizes[i], &width, &height);
  248.  
  249.       if (width * height > best_pixels)
  250.     {
  251.       best_size = sizes[i];
  252.       best_pixels = width * height;
  253.     }
  254.     }
  255.   
  256.   g_free (sizes);
  257.  
  258.   return best_size;
  259. }
  260.  
  261. static void
  262. selection_changed (GtkTreeSelection *selection)
  263. {
  264.   GtkTreeView *treeview;
  265.   StockItemDisplay *display;
  266.   GtkTreeModel *model;
  267.   GtkTreeIter iter;
  268.   
  269.   treeview = gtk_tree_selection_get_tree_view (selection);
  270.   display = g_object_get_data (G_OBJECT (treeview), "stock-display");
  271.  
  272.   if (gtk_tree_selection_get_selected (selection, &model, &iter))
  273.     {
  274.       StockItemInfo *info;
  275.       gchar *str;
  276.       
  277.       gtk_tree_model_get (model, &iter,
  278.                           0, &info,
  279.                           -1);
  280.  
  281.       if (info->small_icon && info->item.label)
  282.         gtk_label_set_text (GTK_LABEL (display->type_label), "Icon and Item");
  283.       else if (info->small_icon)
  284.         gtk_label_set_text (GTK_LABEL (display->type_label), "Icon Only");
  285.       else if (info->item.label)
  286.         gtk_label_set_text (GTK_LABEL (display->type_label), "Item Only");
  287.       else
  288.         gtk_label_set_text (GTK_LABEL (display->type_label), "???????");
  289.  
  290.       gtk_label_set_text (GTK_LABEL (display->macro_label), info->macro);
  291.       gtk_label_set_text (GTK_LABEL (display->id_label), info->id);
  292.  
  293.       if (info->item.label)
  294.         {
  295.           str = g_strdup_printf ("%s %s", info->item.label, info->accel_str);
  296.           gtk_label_set_text_with_mnemonic (GTK_LABEL (display->label_accel_label), str);
  297.           g_free (str);
  298.         }
  299.       else
  300.         {
  301.           gtk_label_set_text (GTK_LABEL (display->label_accel_label), "");
  302.         }
  303.  
  304.       if (info->small_icon)
  305.         gtk_image_set_from_stock (GTK_IMAGE (display->icon_image), info->id,
  306.                                   get_largest_size (info->id));
  307.       else
  308.         gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL);
  309.  
  310.       stock_item_info_free (info);
  311.     }
  312.   else
  313.     {
  314.       gtk_label_set_text (GTK_LABEL (display->type_label), "No selected item");
  315.       gtk_label_set_text (GTK_LABEL (display->macro_label), "");
  316.       gtk_label_set_text (GTK_LABEL (display->id_label), "");
  317.       gtk_label_set_text (GTK_LABEL (display->label_accel_label), "");
  318.       gtk_image_set_from_pixbuf (GTK_IMAGE (display->icon_image), NULL);
  319.     }
  320. }
  321.  
  322. static void
  323. macro_set_func_text (GtkTreeViewColumn *tree_column,
  324.              GtkCellRenderer   *cell,
  325.              GtkTreeModel      *model,
  326.              GtkTreeIter       *iter,
  327.              gpointer           data)
  328. {
  329.   StockItemInfo *info;
  330.   
  331.   gtk_tree_model_get (model, iter,
  332.                       0, &info,
  333.                       -1);
  334.   
  335.   g_object_set (GTK_CELL_RENDERER (cell),
  336.                 "text", info->macro,
  337.                 NULL);
  338.   
  339.   stock_item_info_free (info);
  340. }
  341.  
  342. static void
  343. id_set_func (GtkTreeViewColumn *tree_column,
  344.              GtkCellRenderer   *cell,
  345.              GtkTreeModel      *model,
  346.              GtkTreeIter       *iter,
  347.              gpointer           data)
  348. {
  349.   StockItemInfo *info;
  350.   
  351.   gtk_tree_model_get (model, iter,
  352.                       0, &info,
  353.                       -1);
  354.   
  355.   g_object_set (GTK_CELL_RENDERER (cell),
  356.                 "text", info->id,
  357.                 NULL);
  358.   
  359.   stock_item_info_free (info);
  360. }
  361.  
  362. static void
  363. accel_set_func (GtkTreeViewColumn *tree_column,
  364.                 GtkCellRenderer   *cell,
  365.                 GtkTreeModel      *model,
  366.                 GtkTreeIter       *iter,
  367.                 gpointer           data)
  368. {
  369.   StockItemInfo *info;
  370.   
  371.   gtk_tree_model_get (model, iter,
  372.                       0, &info,
  373.                       -1);
  374.   
  375.   g_object_set (GTK_CELL_RENDERER (cell),
  376.                 "text", info->accel_str,
  377.                 NULL);
  378.   
  379.   stock_item_info_free (info);
  380. }
  381.  
  382. static void
  383. label_set_func (GtkTreeViewColumn *tree_column,
  384.                 GtkCellRenderer   *cell,
  385.                 GtkTreeModel      *model,
  386.                 GtkTreeIter       *iter,
  387.                 gpointer           data)
  388. {
  389.   StockItemInfo *info;
  390.   
  391.   gtk_tree_model_get (model, iter,
  392.                       0, &info,
  393.                       -1);
  394.   
  395.   g_object_set (GTK_CELL_RENDERER (cell),
  396.                 "text", info->item.label,
  397.                 NULL);
  398.   
  399.   stock_item_info_free (info);
  400. }
  401.  
  402. GtkWidget *
  403. do_stock_browser (GtkWidget *do_widget)
  404. {  
  405.   if (!window)
  406.     {
  407.       GtkWidget *frame;
  408.       GtkWidget *vbox;
  409.       GtkWidget *hbox;
  410.       GtkWidget *sw;
  411.       GtkWidget *treeview;
  412.       GtkWidget *align;
  413.       GtkTreeModel *model;
  414.       GtkCellRenderer *cell_renderer;
  415.       StockItemDisplay *display;
  416.       GtkTreeSelection *selection;
  417.       GtkTreeViewColumn *column;
  418.  
  419.       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  420.       gtk_window_set_screen (GTK_WINDOW (window),
  421.                  gtk_widget_get_screen (do_widget));
  422.       gtk_window_set_title (GTK_WINDOW (window), "Stock Icons and Items");
  423.       gtk_window_set_default_size (GTK_WINDOW (window), -1, 500);
  424.  
  425.       g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
  426.       gtk_container_set_border_width (GTK_CONTAINER (window), 8);
  427.  
  428.       hbox = gtk_hbox_new (FALSE, 8);
  429.       gtk_container_add (GTK_CONTAINER (window), hbox);
  430.  
  431.       sw = gtk_scrolled_window_new (NULL, NULL);
  432.       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
  433.                                       GTK_POLICY_NEVER,
  434.                                       GTK_POLICY_AUTOMATIC);
  435.       gtk_box_pack_start (GTK_BOX (hbox), sw, FALSE, FALSE, 0);
  436.  
  437.       model = create_model ();
  438.       
  439.       treeview = gtk_tree_view_new_with_model (model);
  440.  
  441.       g_object_unref (model);
  442.  
  443.       gtk_container_add (GTK_CONTAINER (sw), treeview);
  444.       
  445.       column = gtk_tree_view_column_new ();
  446.       gtk_tree_view_column_set_title (column, "Macro");
  447.  
  448.       cell_renderer = gtk_cell_renderer_pixbuf_new ();
  449.       gtk_tree_view_column_pack_start (column,
  450.                        cell_renderer,
  451.                        FALSE);
  452.       gtk_tree_view_column_set_attributes (column, cell_renderer,
  453.                        "stock_id", 1, NULL);
  454.       cell_renderer = gtk_cell_renderer_text_new ();
  455.       gtk_tree_view_column_pack_start (column,
  456.                        cell_renderer,
  457.                        TRUE);
  458.       gtk_tree_view_column_set_cell_data_func (column, cell_renderer,
  459.                            macro_set_func_text, NULL, NULL);
  460.  
  461.       gtk_tree_view_append_column (GTK_TREE_VIEW (treeview),
  462.                    column);
  463.  
  464.       cell_renderer = gtk_cell_renderer_text_new ();
  465.       gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
  466.                                                   -1,
  467.                                                   "Label",
  468.                                                   cell_renderer,
  469.                                                   label_set_func,
  470.                                                   NULL,
  471.                                                   NULL);
  472.  
  473.       cell_renderer = gtk_cell_renderer_text_new ();
  474.       gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
  475.                                                   -1,
  476.                                                   "Accel",
  477.                                                   cell_renderer,
  478.                                                   accel_set_func,
  479.                                                   NULL,
  480.                                                   NULL);
  481.  
  482.       cell_renderer = gtk_cell_renderer_text_new ();
  483.       gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (treeview),
  484.                                                   -1,
  485.                                                   "ID",
  486.                                                   cell_renderer,
  487.                                                   id_set_func,
  488.                                                   NULL,
  489.                                                   NULL);
  490.       
  491.       align = gtk_alignment_new (0.5, 0.0, 0.0, 0.0);
  492.       gtk_box_pack_end (GTK_BOX (hbox), align, FALSE, FALSE, 0);
  493.       
  494.       frame = gtk_frame_new ("Selected Item");
  495.       gtk_container_add (GTK_CONTAINER (align), frame);
  496.  
  497.       vbox = gtk_vbox_new (FALSE, 8);
  498.       gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  499.       gtk_container_add (GTK_CONTAINER (frame), vbox);
  500.  
  501.       display = g_new (StockItemDisplay, 1);
  502.       g_object_set_data_full (G_OBJECT (treeview),
  503.                               "stock-display",
  504.                               display,
  505.                               g_free); /* free display with treeview */
  506.       
  507.       display->type_label = gtk_label_new (NULL);
  508.       display->macro_label = gtk_label_new (NULL);
  509.       display->id_label = gtk_label_new (NULL);
  510.       display->label_accel_label = gtk_label_new (NULL);
  511.       display->icon_image = gtk_image_new_from_pixbuf (NULL); /* empty image */
  512.  
  513.       gtk_box_pack_start (GTK_BOX (vbox), display->type_label,
  514.                           FALSE, FALSE, 0);
  515.  
  516.       gtk_box_pack_start (GTK_BOX (vbox), display->icon_image,
  517.                           FALSE, FALSE, 0);
  518.       
  519.       gtk_box_pack_start (GTK_BOX (vbox), display->label_accel_label,
  520.                           FALSE, FALSE, 0);
  521.       gtk_box_pack_start (GTK_BOX (vbox), display->macro_label,
  522.                           FALSE, FALSE, 0);
  523.       gtk_box_pack_start (GTK_BOX (vbox), display->id_label,
  524.                           FALSE, FALSE, 0);
  525.  
  526.       selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
  527.       gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
  528.       
  529.       g_signal_connect (selection,
  530.             "changed",
  531.             G_CALLBACK (selection_changed),
  532.             NULL);
  533.     }
  534.  
  535.   if (!GTK_WIDGET_VISIBLE (window))
  536.     {
  537.       gtk_widget_show_all (window);
  538.     }
  539.   else
  540.     {     
  541.       gtk_widget_destroy (window);
  542.       window = NULL;
  543.     }
  544.  
  545.   return window;
  546. }
  547.